import { defineStore } from "pinia";
import { ElMessage } from "element-plus";
import { IRoleBase } from "@/apis/acl/role/type";
import {
  getAllRoleApi,
  addOrUpdateRoleApi,
  deleteRoleApi,
  getRolesByidsApi,
} from "@/apis//acl/role";
import { dateFormat } from "@/utils/tools";
import { MsgEnum, AclEnum, curriedFn } from "../.";
import usePermissionStore from "./permission";
import type { IPermission } from "@/apis/acl/menu/type";

const msg = curriedFn(AclEnum.role);
/**
 * 角色仓库
 */
const useRoleStore = defineStore("roleStore", {
  state: (): {
    roleList: Array<IRoleBase>;
    selectRoles: Array<IRoleBase>;
    currentPage: number;
    pageSize: number;
    totalItem: number;
    keyword: string;
    loading: boolean;
    permissions: Array<IPermission>;
  } => {
    return {
      roleList: [],
      selectRoles: [],
      currentPage: 1,
      pageSize: 10,
      totalItem: 20,
      keyword: "",
      loading: false,
      permissions: [],
    };
  },
  actions: {
    async getRoleList(pager = 1) {
      this.loading = true;
      try {
        const res = await getAllRoleApi(pager, this.pageSize, this.keyword);
        if (res.code === 200) {
          if (!res.data.data) return;
          this.roleList = res.data.data?.map(item => {
            return {
              ...item,
              createdAt: dateFormat(item.createdAt!),
              updatedAt: dateFormat(item.updatedAt!),
            };
          });
          this.totalItem = res.data.meta?.totalItems!;
          this.currentPage = res.data.meta?.currentPage!;
          this.pageSize = res.data.meta?.itemPerPage!;
          ElMessage(msg(MsgEnum.get));
        }
      } catch (error: any) {
        ElMessage.error(error.message);
      } finally {
        this.loading = false;
      }
    },

    async getMaryRoles(ids: string[]) {
      this.loading = true;
      try {
        const res = await getRolesByidsApi(ids);
        if (res.code === 200) {
          if (!res.data) return;
          this.selectRoles = [...res.data];
          ElMessage(msg(MsgEnum.get));
        }
      } catch (error: any) {
        ElMessage.error(error.message);
      } finally {
        this.loading = false;
      }
    },

    async addOrUpdateRole(role: IRoleBase) {
      this.loading = true;
      try {
        const res = await addOrUpdateRoleApi(role);
        if (res.code === 200) {
          await this.getRoleList(role._id ? this.currentPage : 1);
          ElMessage.success(role._id ? msg(MsgEnum.update) : msg(MsgEnum.add));
        }
      } catch (error: any) {
        ElMessage.error(error.message);
      } finally {
        this.loading = false;
      }
    },

    async deleteRole(id: string) {
      this.loading = true;
      try {
        const res = await deleteRoleApi(id);
        if (res.code === 200) {
          await this.getRoleList(
            this.roleList.length > 1
              ? this.currentPage
              : this.currentPage === 1
              ? 1
              : this.currentPage - 1
          );
          ElMessage.success(msg(MsgEnum.delete));
        }
      } catch (error: any) {
        ElMessage.error(error.message);
      } finally {
        this.loading = false;
      }
    },

    async getPermissions() {
      const pr = usePermissionStore();
      const res = await pr.getPermissionList();
      if (res === "ok") {
        this.permissions = pr.permissionList;
      }
    },
  },
  getters: {
    selectPermissionIds: state => {
      if (state.selectRoles.length === 0) return [];
      return state.selectRoles.reduce((pre, cur) => {
        pre = [...pre, ...(cur.permissionIds as string[])];
        return [...new Set(pre)];
      }, [] as string[]);
    },
    /**
     * 角色与id键值对
     * @param state
     * @returns
     */
    rolePairs: state => {
      if (state.roleList.length === 0) return {};
      return state.roleList.reduce((obj, cur) => {
        obj[cur.name] = cur._id as string;
        return obj;
      }, {} as { [key: string]: string });
    },
    /**
     * 获取角色的中文名称集合；
     * this引用必须是如下格式；
     * @returns
     */
    roleNames(): string[] {
      return Object.keys(this.rolePairs) || [];
    },
  },
});

export default useRoleStore;
